﻿using System;
using System.IO;
using System.IO.Ports;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Text.RegularExpressions;

namespace Bash_config_v2._1
{ 
    public partial class Form1 : Form
    {
        public bool IsReceving = false;
        SerialPort comm = new SerialPort();
        StringBuilder builder = new StringBuilder();
        string[] PortList = new string[] {};
        int number = 0;
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

            try
            {
                //添加串口项目
                PortList = SerialPort.GetPortNames();
                Array.Sort(PortList);
                foreach (string s in PortList)
                {//获取有多少个COM口
                    //System.Diagnostics.Debug.WriteLine(s);
                    cmb_com.Items.Add(s);
                    cmb_com.SelectedIndex = 0;
                }
            }
            catch
            {
                MessageBox.Show("找不到通讯串口", "Basch_Config_v2.2");
            }
    
            Control.CheckForIllegalCrossThreadCalls = false;
            btn_read.Enabled = false;
        }

        private void btn_conn_Click(object sender, EventArgs e)
        {
            
            try
            {
                //***避免串口死锁***
                //写超时，如果底层串口驱动效率问题，能有效的避免死锁。
                comm.WriteTimeout = 1000;
                //读超时，同上。
                comm.ReadTimeout = 1000;
                //回车换行。
                comm.NewLine = "\r\n";
                //注册事件。
                comm.DataReceived += new SerialDataReceivedEventHandler(this.comm_DataReceived);
                //***避免串口死锁***
                comm.PortName = cmb_com.Text;
                comm.BaudRate = 19200;
                comm.DataBits = 8;
                comm.Parity = Parity.None;
                comm.StopBits = StopBits.One;
                comm.DtrEnable = true;
                comm.RtsEnable = true;
                comm.Open();
                comm.DiscardInBuffer();
                if (comm.IsOpen)
                {
                    btn_break.Enabled = true;
                    btn_conn.Enabled = false;
                    btn_start.Enabled = false;
                    btn_pause.Enabled = true;
                    txtBoxSend.Focus();
                }
  
            }
            catch(Exception e1)
            {
                comm = new SerialPort();
                MessageBox.Show(e1.Message);
            }
            btn_read.Enabled = false;
            btn_ant.Enabled = false;
            btn_power.Enabled = false;
            btn_freq.Enabled = false;
            btn_noTag.Enabled = false;
            btn_TimeOut.Enabled = false;
           
        }

        private void comm_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
  //          DateTime dt = DateTime.Now;
            try
            {
                //***正在接收状态指示。
                IsReceving = true;
                //读入收到的数据。
                int Len = comm.BytesToRead;
                if (Len < 1)
                {
                    //***接收完成状态指示。
                    IsReceving = false;
                    return;
                }

                byte[] data = new byte[Len];
                comm.Read(data, 0, Len);

                //字符串处理。
                string Str = Encoding.GetEncoding("GB2312").GetString(data);
   //             txtDataBox.AppendText(dt.ToShortTimeString().ToString());
                //使用委托跨线程读取数据。
                txtDataBox.Invoke(new EventHandler(delegate
                {
                    txtDataBox.AppendText(Str);
                    txtDataBox.ScrollToCaret();
                    //***完成处理字符串。
                    IsReceving = false;
                }
                ));
                /*
                int n = comm.BytesToRead;//先记录下来，避免某种原因，人为的原因，操作几次之间时间长，缓存不一致  
                byte[] buf = new byte[n];//声明一个临时数组存储当前来的串口数据  
      //          received_count += n;//增加接收计数  
                comm.Read(buf, 0, n); ;//读取缓冲数据  
                builder.Clear();//清除字符串构造器的内容  
                //因为要访问ui资源，所以需要使用invoke方式同步ui。  
                this.Invoke((EventHandler)(delegate
                {
                    //直接按ASCII规则转换成字符串  
                    builder.Append(Encoding.ASCII.GetString(buf));
                    //追加的形式添加到文本框末端，并滚动到最后。  
                    txtDataBox.AppendText(builder.ToString());
                }));
                    */

                //            SerialPort sp = (SerialPort)sender;
                //           string indata = sp.ReadExisting();

                //          txtDataBox.AppendText(comm.ReadLine() + "\r"); //注意：回车换行必须这样写，单独使用"\r"和"\n"都不会有效果  
                //         comm.DiscardInBuffer(); 
            }
            catch (Exception Err)
            {
                MessageBox.Show(Err.Message, "Basch_Config_v2.2");
            }
        }

        private void SendStringData(string data)
        {
            string SendStr = data + '\r';
            if (comm.IsOpen)
            {
                comm.WriteLine(SendStr);
            }
            else
            {
                MessageBox.Show("串口没有打开");
            }
        }
        private void ClosePort()
        {
            //安全关闭当前串口。
            //***避免串口死锁***
            //注销串口中断接收事件，避免下次再执行进来，造成死锁。
            comm.DataReceived -= this.comm_DataReceived;
            while (IsReceving)
            {
                //处理串口接收事件及其它系统消息。
                Application.DoEvents();
            }
            //现在没有死锁，可以关闭串口。
            comm.Close();
            //***避免串口死锁***
        }

        private void btn_txtSend_Click(object sender, EventArgs e)
        {


            try
            {
                string txt = txtBoxSend.Text;
                Byte[] EncodeByte = new byte[txt.Length * 2];
                EncodeByte = Encoding.GetEncoding("GB2312").GetBytes(txt);
                int leng = EncodeByte.Length;
                comm.Write(EncodeByte, 0, leng);
            }
            catch (Exception err)
            {
                MessageBox.Show(err.Message, "Basch_Config_v2.2");
            }
              
       
        }

        private void btn_clear_Click(object sender, EventArgs e)
        {
            txtDataBox.Text = "";
        }

        private void btn_break_Click(object sender, EventArgs e)
        {
            ClosePort();
            if (!comm.IsOpen)
            {
                btn_conn.Enabled = true;
                btn_break.Enabled = false;
                btn_start.Enabled = false;
                btn_pause.Enabled = false;
                btn_read.Enabled = false;
                btn_ant.Enabled = false;
                btn_power.Enabled = false;
                btn_freq.Enabled = false;
                btn_noTag.Enabled = false;
                btn_TimeOut.Enabled = false;
            }
        }

        private void btn_pause_Click(object sender, EventArgs e)
        {
            
                comm.Write("S");
                btn_read.Enabled = true;
                btn_start.Enabled = true;
                btn_pause.Enabled = false;
                comm.DataReceived -= this.comm_DataReceived;

                btn_ant.Enabled = true;
                btn_power.Enabled = true;
                btn_freq.Enabled = true;
                btn_noTag.Enabled = true;
                btn_TimeOut.Enabled = true;

            /*
                int len1 = comm.BytesToRead;
               // while (len1 < 1) ;
                txtBoxMor.Text = len1.ToString();

                byte[] data1 = new byte[len1];
                comm.Read(data1, 0, len1);
           
                //字符串处理。
                string str1 = Encoding.GetEncoding("GB2312").GetString(data1);
                if (str1 == "S")
                {
                    txtBoxMor.Text = "已暂停";
                }
                else
                {
                    txtBoxMor.Text = "暂停不了";
                }
          */  
            
        }

        private void btn_start_Click(object sender, EventArgs e)
        {
            comm.Write("s");
            btn_read.Enabled = false;
            btn_start.Enabled = false;
            btn_pause.Enabled = true;
            comm.DataReceived += this.comm_DataReceived;

            btn_ant.Enabled = false;
            btn_power.Enabled = false;
            btn_freq.Enabled = false;
            btn_noTag.Enabled = false;
            btn_TimeOut.Enabled = false;
       }

        private void btn_read_Click(object sender, EventArgs e)
        {
            comm.DiscardInBuffer();
           comm.Write("V");
           
           while (comm.BytesToRead < 44)
           {
               if (comm.BytesToRead == 43)
               {
                   MessageBox.Show("串口通讯出现错误，请按顺序点击->开始->暂停一次！");
                   return;
               }
           }
            
           number = comm.BytesToRead;
           byte[] buf = new byte[44];
           comm.Read(buf, 0, 44);  
           string str = Encoding.ASCII.GetString(buf);
       

            //read version
            System.Text.StringBuilder builder = new System.Text.StringBuilder();
            char[] FW = new char[] { str[0], str[1], str[2] };
            builder.AppendLine("固件:");
            builder.Append(FW);
            builder.AppendLine(" ");
            char[] HW = new char[] { str[3], str[4], str[5] };
            builder.AppendLine("模块:");
            builder.Append(FW);
            builder.AppendLine(" ");
            char[] SN = new char[] { str[6], str[7], str[8], str[9] };
            builder.AppendLine("S/N:");
            builder.Append(SN);
            txt_version.Text = builder.ToString();
      //      string str = System.Text.Encoding.Default.GetString(buf);
      //      char[] cha = str.ToCharArray(0, str.Length);
      //      string str1 = Convert.ToString(cha[11]);
      //      string s = cha[11].ToString();
            int ant = int.Parse(str[11].ToString(), System.Globalization.NumberStyles.AllowHexSpecifier);
              if ((ant & 0x1) == 1)
              {
                  checkBox1.Checked = true;
              }
              else
              {
                  checkBox1.Checked = false;
              }
              if ((ant & 0x2) == 0x2)
              {
                  checkBox4.Checked = true;
              }
              else
              {
                  checkBox4.Checked = false;
              }
              if ((ant & 0x4) == 0x4)
              {
                  checkBox2.Checked = true;
              }
              else
              {
                  checkBox2.Checked = false;
              }
              if ((ant & 0x8) == 0x8)
              {
                  checkBox3.Checked = true;
              }
              else
              {
                  checkBox3.Checked = false;
              }
            //     str1= Convert.ToString(char[])
            //     txtBoxMor.AppendText(Convert.ToString(buf));
            //     comm.DiscardInBuffer();
            //     comm.Write("v");       
            //     txt_version.Text = Encoding.ASCII.GetString(buf);
            //     txt_version.Text = comm.ReadLine(); 
            //     int u = BitConverter.ToInt32(buf, 0);

            // read timeout
              char[] timeout = new char[] { str[16], str[17], str[18], str[19] };
              System.Text.StringBuilder sb = new System.Text.StringBuilder();
              sb.Append(timeout);
              int TimeOut = int.Parse(sb.ToString(), System.Globalization.NumberStyles.AllowHexSpecifier);
              txtTimeOut.Text = TimeOut.ToString();

            // read frequence
              sb.Remove(0, sb.Length);
              char[] freq = new char[] { str[20], str[21], str[22], str[23], str[24], str[25], };       
              sb.Append(freq);
              int Frequ = int.Parse(sb.ToString(), System.Globalization.NumberStyles.AllowHexSpecifier);
              txtFreq.Text = (Frequ / 1000).ToString();

              //read No_Tag_Present
              sb.Remove(0, sb.Length);
              char[] no_tag_present = new char[] { str[26], str[27] };
              sb.Append(no_tag_present);
              int No_Tag_Present = int.Parse(sb.ToString(), System.Globalization.NumberStyles.AllowHexSpecifier);
              txtNo.Text = No_Tag_Present.ToString();

            // read power
              sb.Remove(0, sb.Length);
              char[] ant1_power = new char[] { str[28], str[29], str[30], str[31] };
              sb.Append(ant1_power);
              int Ant1_Power = int.Parse(sb.ToString(), System.Globalization.NumberStyles.AllowHexSpecifier);
              txtPower1.Text = Ant1_Power.ToString();

              sb.Remove(0, sb.Length);
              char[] ant2_power = new char[] { str[36], str[37], str[38], str[39] };
              sb.Append(ant2_power);
              int Ant2_Power = int.Parse(sb.ToString(), System.Globalization.NumberStyles.AllowHexSpecifier);
              txtPower2.Text = Ant2_Power.ToString();

              sb.Remove(0, sb.Length);
              char[] ant3_power = new char[] { str[40], str[41], str[42], str[43] };
              sb.Append(ant3_power);
              int Ant3_Power = int.Parse(sb.ToString(), System.Globalization.NumberStyles.AllowHexSpecifier);
              txtPower3.Text = Ant3_Power.ToString();

              sb.Remove(0, sb.Length);
              char[] ant4_power = new char[] { str[32], str[33], str[34], str[35] };                                              
              sb.Append(ant4_power);
              int Ant4_Power = int.Parse(sb.ToString(), System.Globalization.NumberStyles.AllowHexSpecifier);
              txtPower4.Text = Ant4_Power.ToString();
              
        }

        

        private void btn_noTag_Click(object sender, EventArgs e)
        {
            comm.DiscardInBuffer();
            byte[] buffer= new byte[1];
  //          byte[] noTag = System.Text.Encoding.Default.GetBytes(txtNo.Text);
            
              try 
	          {	        
		          byte notag=byte.Parse(txtNo.Text);
                  buffer = BitConverter.GetBytes(notag);
	          }
	          catch (Exception e3)
              {
	              MessageBox.Show("次数的值应该再0~255之间！");
                  return;
	          }
            
                comm.Write("B");
                comm.Write(buffer, 0, 1);
                while (comm.BytesToRead < 1) ;
                comm.Read(buffer, 0, 1);
                if ((char)buffer[0] == 'B')
                {
                    txtBoxMor.AppendText("未读到标签次数已更新"+"\n");
                }
                else
                {
                    txtBoxMor.AppendText("未读到标签次数更新失败" + "\n");
                }
          
        }

        private void btn_TimeOut_Click(object sender, EventArgs e)
        {
            comm.DiscardInBuffer();
            byte[] buffer = new byte[2];

            try
            {
                UInt16 timeOut = UInt16.Parse(txtTimeOut.Text);
                buffer = BitConverter.GetBytes(timeOut);
            }
            catch (Exception e2)
            {

                MessageBox.Show("停留时间应该再0~65535之间！");
                return;
            }
                byte[] buf_reverse= new byte[] {buffer[1],buffer[0]};
                comm.Write("T");
                comm.Write(buf_reverse, 0, 2);
                while (comm.BytesToRead < 1) ;
                comm.Read(buffer, 0, 1);
                if ((char)buffer[0] == 'T')
                {
                    txtBoxMor.AppendText("停留时间已更新"+"\n");
                }
                else
                {
                    txtBoxMor.AppendText("停留时间更新失败" + "\n");
                }
            }

        private void btn_freq_Click(object sender, EventArgs e)
        {
            comm.DiscardInBuffer();
            byte[] buffer = new byte[3];
            // byte[] noTag = System.Text.Encoding.Default.GetBytes(txtNo.Text);      
              try 
	          {	        
		         UInt32 freq = UInt32.Parse(txtFreq.Text)*1000;
                   buffer = BitConverter.GetBytes(freq);
                   byte[] buf_reverse = new byte[] { buffer[2], buffer[1], buffer[0] };
                  if(freq<=915000 && freq>=860000)
                  {

                      try
                      {
                          comm.Write("F");
                          comm.Write(buf_reverse, 0, 3);
                          while (comm.BytesToRead < 1) ;
                          comm.Read(buffer, 0, 1);
                          if ((char)buffer[0] == 'F')
                          {
                              txtBoxMor.AppendText("频率已更新" + "\n");
                          }
                          else
                          {
                              txtBoxMor.AppendText("频率更新失败" + "\n");
                          }
                      }
                      catch (Exception e4)
                      {

                          MessageBox.Show("串口无法访问！");
                          return;
                      }
                  }else
                  {
                      MessageBox.Show("频率的范围在860~915MHz之间");
                  }
	          }
	          catch (Exception e3)
	         {
	               MessageBox.Show("频率应该填整数值");
                   return;
	         }   
            
             
        }

        private void btn_power_Click(object sender, EventArgs e)
        {
            comm.DiscardInBuffer();
            byte[] buf = new byte[8];
            byte[] buffer =new byte[2];
            // byte[] noTag = System.Text.Encoding.Default.GetBytes(txtNo.Text);      
            try
            {
                UInt16 power1 = UInt16.Parse(txtPower1.Text);
                buffer = BitConverter.GetBytes(power1);
                buf[0] = buffer[1];
                buf[1] = buffer[0];

                UInt16 power2 = UInt16.Parse(txtPower2.Text);
                buffer = BitConverter.GetBytes(power2);
                buf[4] = buffer[1];
                buf[5] = buffer[0];

                UInt16 power3 = UInt16.Parse(txtPower3.Text);
                buffer = BitConverter.GetBytes(power3);
                buf[6] = buffer[1];
                buf[7] = buffer[0];

                UInt16 power4 = UInt16.Parse(txtPower4.Text);
                buffer = BitConverter.GetBytes(power4);
                buf[2] = buffer[1];
                buf[3] = buffer[0];

                if ((power1 <= 330 && power1 >= 10) && (power2 <= 330 && power2 >= 10) && (power3 <= 330 && power3 >= 10) && (power4 <= 330 && power4 >= 10))
                {

                    try
                    {
                        comm.Write("P");
                        comm.Write(buf, 0, 8);
                        while (comm.BytesToRead < 1) ;
                        comm.Read(buffer, 0, 1);
                        if ((char)buffer[0] == 'P')
                        {
                            txtBoxMor.AppendText("功率已更新" + "\n");
                        }
                        else
                        {
                            txtBoxMor.AppendText("功率更新失败" + "\n");
                        }
                    }
                    catch (Exception e4)
                    {

                        MessageBox.Show("串口无法访问！");
                        return;
                    }
                }
                else
                {
                    MessageBox.Show("功率的范围在10-330ddBm之间");
                }
            }
            catch (Exception e3)
            {
                MessageBox.Show("应该填整数值");
                return;
            }
        }

        private void btn_ant_Click(object sender, EventArgs e)
        {
                comm.DiscardInBuffer();
                byte[] buffer = new byte[1];
                int ant = 0;
                if (checkBox1.Checked)
                {
                    ant |= 0x1;
                }
                if (checkBox2.Checked)
                {
                    ant |= 0x4;
                }
                if (checkBox3.Checked)
                {
                    ant |= 0x8;
                }
                if (checkBox4.Checked)
                {
                    ant |= 0x2;
                }
                buffer[0] = (byte)ant;
                comm.Write("A");
                comm.Write(buffer, 0, 1);
                while (comm.BytesToRead < 1) ;
                comm.Read(buffer, 0, 1);
                if ((char)buffer[0] == 'A')
                {
                    txtBoxMor.AppendText("天线已更新" + "\n");
                }
                else
                {
                    txtBoxMor.AppendText("天线更新失败" + "\n");
                }
              
        }

        private void low1_Click(object sender, EventArgs e)
        {
            comm.DiscardInBuffer();
            comm.Write("1");
        }

        private void high1_Click(object sender, EventArgs e)
        {
            comm.DiscardInBuffer();
            comm.Write("2");
        }

        private void low2_Click(object sender, EventArgs e)
        {
            comm.DiscardInBuffer();
            comm.Write("3");
        }

        private void high2_Click(object sender, EventArgs e)
        {
            comm.DiscardInBuffer();
            comm.Write("4");
        }

        private void low3_Click(object sender, EventArgs e)
        {
            comm.DiscardInBuffer();
            comm.Write("5");
        }

        private void high3_Click(object sender, EventArgs e)
        {
            comm.DiscardInBuffer();
            comm.Write("6");
        }

        private void low4_Click(object sender, EventArgs e)
        {
            comm.DiscardInBuffer();
            comm.Write("7");
        }

        private void high4_Click(object sender, EventArgs e)
        {
            comm.DiscardInBuffer();
            comm.Write("8");
        }

        private void com_click(object sender, EventArgs e)
        {
            PortList = SerialPort.GetPortNames();
            if(PortList==null)
            {
                return;
            }
            else
            {
                foreach (string s in PortList)
                    cmb_com.Items.Add(s);
            }
        }

        private void staus_help_Click(object sender, EventArgs e)
        {
            MessageBox.Show("读卡器开机设置为自动工作状态，点击暂停按钮后才能点击开始按钮。读取和设置参数只能在暂停状态下进行！");
        }

        private void anta_help_Click(object sender, EventArgs e)
        {
            MessageBox.Show("可以单独设置每个天线的开关，实际工作时要保证每个天线口都连有天线，以免长时间发热损坏天线口。");
        }

        private void pwr_help_Click(object sender, EventArgs e)
        {
            MessageBox.Show("天线的功率范围在100~300ddBm,一般情况下在120~250ddBm之间即可。");
        }

        private void freq_help_Click(object sender, EventArgs e)
        {
            MessageBox.Show("频率范围在860-915MHz之间。");
        }

        private void NoTag_help_Click(object sender, EventArgs e)
        {
            MessageBox.Show("未读到标签次数就是该路天线如果在该次数内都没读到标签将输出一个低电平。");
        }

        private void TimeOut_help_Click(object sender, EventArgs e)
        {
            MessageBox.Show("停留时间为射频电磁波在每个天线上的停留时间，超过规定时间将按照1-4的顺序切换。");
        }
      }   
}
